using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Reflection;
using Common;

namespace BusinessEntity.Common
{
    [Serializable]
    public class SortableCollection<T> : BindingList<T> 
    {
        protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
        {
            PropertyInfo sortingProp = typeof(T).GetProperty(prop.Name);
            if (typeof(IComparable).IsAssignableFrom(sortingProp.PropertyType))
            {
                // The type is an IComparable and so we can compare
                for (int i = this.Count - 1; i > 0; i--)
                {
                    for (int j = 0; j < i; j++)
                    {
                        // Compare the properties of the objects
                        object lhs = sortingProp.GetValue(this[j], null);
                        object rhs = sortingProp.GetValue(this[j + 1], null);
                        // If ascending, compare left to right, otherwise compare right to left
                        if ((direction == ListSortDirection.Ascending && ((IComparable)lhs).CompareTo(rhs) > 0)
                            || (direction == ListSortDirection.Descending && ((IComparable)rhs).CompareTo(lhs) > 0))
                        {
                            T temp = this[j];
                            this[j] = this[j + 1];
                            this[j + 1] = temp;
                        }
                    }
                }
            }
        }

        protected override bool SupportsSortingCore
        {
            get { return true; }
        }

        public void Sort(string prop, SortDirection direction)
        {
            PropertyDescriptorCollection propDescriptors = TypeDescriptor.GetProperties(typeof(T));
            if (direction == SortDirection.ASC)
            {
                this.ApplySortCore(propDescriptors[prop],ListSortDirection.Ascending);
            }
            else if (direction == SortDirection.DESC)
            {
                this.ApplySortCore(propDescriptors[prop], ListSortDirection.Descending);
            }
        }

        public virtual void AddRange(SortableCollection<T> collection)
        {
            foreach (var item in collection)
            {
                this.Items.Add(item);
            }
        }
        public virtual void AddRange(List<T> collection)
        {
            foreach (var item in collection)
            {
                this.Items.Add(item);
            }
        }

     
    }
}
